/**
 * <copyright>
 * Copyrigth 2007 Aurelien Moreau
 *
 * This file is part of ProcessShop.
 *
 * ProcessShop is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * ProcessShop is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with ProcessShop; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * </copyright>
 *
 * $Id$
 */
package net.yienyien.process.bpmn2bpel.wizards;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import net.yienyien.process.bpd.BPDModel;
import net.yienyien.process.bpel.generator.BPELGenerationException;
import net.yienyien.process.bpel.generator.BPELGenerator;
import net.yienyien.process.bpel.generator.BPELGeneratorListener;
import net.yienyien.process.bpel.generator.Contrib;
import net.yienyien.process.bpel.generator.Production;
import net.yienyien.process.bpel.generator.controlFlow.ControlFlowContrib;

import net.yienyien.process.bpel.generator.init.InitContrib;
import net.yienyien.process.bpel.generator.partner.PartnerContrib;
import net.yienyien.process.pim.ProcessInformation;
import net.yienyien.process.pmm.Bindings;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.wst.wsdl.Definition;
import org.open.oasis.docs.wsbpel._2._0.process.abstract_.TProcess;
import org.open.oasis.docs.wsbpel._2._0.process.abstract_.util.AbstractXMLProcessor;

/**
 * This is a sample new wizard. Its role is to create a new file 
 * resource in the provided container. If the container resource
 * (a folder or a project) is selected in the workspace 
 * when the wizard is opened, it will accept it as the target
 * container. The wizard creates one file with the extension
 * "bpel". If a sample multi-page editor (also available
 * as a template) is registered for the same extension, it will
 * be able to open it.
 */

public class SampleNewWizard extends Wizard implements INewWizard {
	private SampleNewWizardPage page;

	/**
	 * Constructor for SampleNewWizard.
	 */
	public SampleNewWizard() {
		super();
		setNeedsProgressMonitor(true);
	}
	
	/**
	 * Adding the page to the wizard.
	 */

	public void addPages() {
		page = new SampleNewWizardPage();
		addPage(page);
	}

	/**
	 * This method is called when 'Finish' button is pressed in
	 * the wizard. We will create an operation and run it
	 * using wizard as execution context.
	 */
	public boolean performFinish() {
		final BPDModel bpd=page.getBPD();
		final Bindings pmm=page.getPMM();
		final ProcessInformation pim=page.getPIM();
		final String out=page.getOutFile();
		
		IRunnableWithProgress op = new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor) throws InvocationTargetException {
				try {
					doFinish(out, bpd, pmm, pim, monitor);
				} catch (CoreException e) {
					throw new InvocationTargetException(e);
				} finally {
					monitor.done();
				}
			}
		};
		try {
			getContainer().run(true, false, op);
		} catch (InterruptedException e) {
			return false;
		} catch (InvocationTargetException e) {
			e.printStackTrace();
			Throwable realException = e.getTargetException();
			MessageDialog.openError(getShell(), "Error", realException.getMessage());
			return false;
		}
		return true;
	}
	
	/**
	 * The worker method. It will find the container, create the
	 * file if missing or just replace its contents, and open
	 * the editor on the newly created file.
	 */

	private void doFinish(String out, BPDModel bpd,Bindings pmm, ProcessInformation pim, final IProgressMonitor monitor)
		throws CoreException {
				
		BPELGenerator generator=new BPELGenerator();
		HashMap<String, EObject> arg=new HashMap<String, EObject>();
		arg.put(InitContrib.KEY, pim);
		arg.put(PartnerContrib.KEY, pmm);
		arg.put(ControlFlowContrib.KEY, bpd);

		monitor.beginTask("Generate BPEL", generator.getContribs().size());
		generator.addListener(new BPELGeneratorListener() {
			@Override
			public void end(Contrib contrib) {
				monitor.worked(1);
			}

			@Override
			public void start(Contrib contrib) {
			}

			@Override
			public void prepare(Contrib contrib) {
			}});
		
		
		Production prod;
		try {
			prod = generator.generate(arg);
		} catch (BPELGenerationException e1) {
			e1.printStackTrace();
			return; //TODO
		}
		ResourceSet set=new ResourceSetImpl();
		Resource current;
		String uri;
		
		monitor.beginTask("Save BPEL", 1);
		uri=out+"/"+prod.getProcess().getName()+".bpel";
		current=set.createResource(URI.createFileURI(uri));
		current.getContents().add(prod.getProcess());
		AbstractXMLProcessor processor=new AbstractXMLProcessor();
		try {
			processor.save(new FileOutputStream(new File(uri)), current, null);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		monitor.worked(1);
		
		monitor.beginTask("Save process wsdl", 1);
		current=set.createResource(URI.createFileURI(out+"/"+prod.getProcess().getName()+".wsdl"));
		current.getContents().add(prod.getProcessWSDL());
		try {
			current.save(null);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		monitor.beginTask("Save modified wsdl", prod.getWSDLs().size());
		int c=0;
		for(Definition def: prod.getWSDLs()) {
			String name=(def.eResource()!=null)? def.eResource().getURI().lastSegment(): "service"+(c++);
			uri=out+"/"+name;
			current=set.createResource(URI.createFileURI(uri));
			current.getContents().add(def);
			try {
				current.save(null);
			} catch (IOException e) {
				e.printStackTrace();
			}
			monitor.worked(1);
		}
		
		
	}

	@Override
	public void init(IWorkbench workbench, IStructuredSelection selection) {

		
	}





}